﻿using IronBefunge.Core.InstructionHandlers;
using IronBefunge.Core.Tests.Mocks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace IronBefunge.Core.Tests.InstructionHandlers
{
	[TestClass]
	public sealed class InputInstructionHandlerTests : InstructionHandlerTests
	{
		internal override ReadOnlyCollection<char> GetExpectedHandledInstructions()
		{
			return new List<char>() { InputInstructionHandler.AsciiInstruction,
				InputInstructionHandler.NumericInstruction }.AsReadOnly();
		}

		internal override Type GetHandlerType()
		{
			return typeof(InputInstructionHandler);
		}

		[TestMethod]
		public void HandleAscii()
		{
			var cells = new List<Cell>() { new Cell(
				new Point(0, 0), InputInstructionHandler.AsciiInstruction) };

			var reader = new MockAsciiTextReader(88);
			var stackCount = 0;

			InstructionHandlerTests.Run(new InputInstructionHandler(), cells, null, 
				(context, result) =>
				{
					Assert.AreEqual(stackCount + 1, context.Values.Count);
					Assert.AreEqual(88, context.Values.Peek());
				}, reader);
		}

		[TestMethod]
		public void HandleNumeric()
		{
			var cells = new List<Cell>() { new Cell(
				new Point(0, 0), InputInstructionHandler.NumericInstruction) };

			var reader = new MockNumericTextReader("123456");
			var stackCount = 0;

			InstructionHandlerTests.Run(new InputInstructionHandler(), cells, null,
				(context, result) =>
				{
					Assert.AreEqual(stackCount + 1, context.Values.Count);
					Assert.AreEqual(123456, context.Values.Peek());
				}, reader);
		}

		[TestMethod]
		public void HandleNumericWithInvalidData()
		{
			var cells = new List<Cell>() { new Cell(
				new Point(0, 0), InputInstructionHandler.NumericInstruction) };

			var reader = new MockNumericTextReader("quux");
			var stackCount = 0;

			InstructionHandlerTests.Run(new InputInstructionHandler(), cells, null,
				(context, result) =>
				{
					Assert.AreEqual(stackCount, context.Values.Count);
				}, reader);
		}
	}
}
